/*-------------------------------------------------------------------------
FileName     : ConnectMeta.h
Description  : 连接信息
remark       : 
Modification :
--------------------------------------------------------------------------
   1、Date  2020-08-20       create     hejl 
-------------------------------------------------------------------------*/
#ifndef _CONNECT_META_H_
#define _CONNECT_META_H_
#include <cstddef>
#include <thread>
#include <string>
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <atomic>
#include <queue>
#include <set>
#include <functional>
#include <unistd.h>

using namespace std;

enum FdState {
    FDS_INITIAL_CUSTOM = 0,
    FDS_INITIAL_LISTEN = 1,
    FDS_INITIAL_CONNECT = 2,

    FDS_TIMERFD = 9,
    FDS_ACCEPTING = 10,
    FDS_CONNECTING = 11,
    FDS_ESTABLISH = 12,
    FDS_CLOSE = 21,
    FDS_ERROR = 22,
};

#define ACTIVE_STOP_REASON "active_close"

class ConnectMeta : public enable_shared_from_this<ConnectMeta>
{
private:
    int epfd;
    int actFd;
    int objId;
    atomic_int evFlag;  // use: EPOLLIN | EPOLLOUT | EPOLLET | EPOLLONESHOT
    atomic<FdState> fdState;
    string name;
    string errMsg;

    std::mutex readMtx;
    string readingMsg;
    std::queue<string> readQueue;
    std::mutex writeMtx;
    std::queue<string> writeQueue;
    string writingMsg;
    unsigned writePosition;

    time_t begTime;
    time_t endTime;
    size_t sendBytes;
    size_t recvBytes;

public:
    function<void(queue<string>&, string&, weak_ptr<ConnectMeta>)> splitReqFunc; // 报文分拆
    function<void(const string&, weak_ptr<ConnectMeta>)> onMessageReachFunc;
    function<void(int cliFd, shared_ptr<ConnectMeta>)> onAcceptFunc;
    function<void(int, const string&)> onCloseFunc;
    function<void(int fd, shared_ptr<ConnectMeta>)> _onRemoveRefFunc; // no reset normally
    function<void(void)> onTimerFunc;
    function<void(bool,shared_ptr<ConnectMeta>)> onConnectResultFunc;
 

public:
    ConnectMeta(int epfd, int actfd, FdState fds = FDS_INITIAL_CUSTOM);
    ~ConnectMeta();
    
    ConnectMeta* cloneNew(int cliFd, FdState fds); // 返回new结果，由调用者维护
    void start(); // start之前可以给用户设置各callback的机会
    void stop(bool isCallCB);
    string toString();
    int sendMsg(const string& msg);

    void setName(const string& connName);
    void addAliasName(const string& aliasName);
    void delAliasName(const string& aliasName);

    int addEvt(int eventFg); // eventFg取值 EPOLLIN | EPOLLOUT | EPOLLET | EPOLLONESHOT
    int rmEvt(int eventFg);
    int setEvt(int eventFg); // eventFg=0 remove ev
	int changeActFd(int actfd);

    int setKeepAlive(int idleSec);
    int setSndBuffSize(int bytes);
    int setRcvBuffSize(int bytes);

    int onEpollEvent(int events);

private:
    int _recv();
    int _send();
    void oneShotUpdate();
    void _stop(bool isCallCB);
};

#define INVALID_FD (-1)
#define IFCLOSEFD(fd) if(-1!=fd){close(fd); fd=-1;}
using ConnectMetaSPtr = shared_ptr<ConnectMeta>;
using ConnectMetaWkPtr = weak_ptr<ConnectMeta>;


#endif